#include <stdlib.h>
#include <stdio.h>
#include "dsstring.h" // 请不要删除，否则检查不通过
//这一道题题目叙述的模棱两可,难绷QAQ
//借鉴往年大佬的代码才搞明白题目每个参量具体含义orz
//pos：第pos个字符
//BLString中的len:所有字符个数而非Block个数
//blstr_substr中的len个字符中存在BLS_BLANK '#' 
//复制到sub中的子串除末尾有时需空格填充外，内部不存在BLS_BLANK '#'
//如果pos位置后len个字符中存在超界,仍然返回true
bool blstr_substr(BLString src, int pos, int len, BLString *sub) {
    if(pos<0||pos>src.len||len<=0||sub==NULL){//参数合法性检查
        return false;
    }
//头部初始化
    sub->head=(Block*)malloc(sizeof(Block));
    sub->head->next=NULL;
    Block *src_pointer=src.head;//src的移动操作指针
    Block *sub_pointer=sub->head;//sub的移动操作指针
    int count=0,src_index=0,sub_index=0;//count用来判断是否到src中第pos个字符,两个index表示ch[]的下标
//提取子串
    while(src_pointer!=NULL&&(sub->len)<len&&src_pointer->ch[src_index]!=BLS_BLANK){//确保源字符串还有块可读&&复制字符未完&&复制字符非BLS_BLANK '#'     
        if(count<pos){
            if(src_index==BLOCK_SIZE-1){//判断是否访问下一个Block
                src_pointer=src_pointer->next;
                src_index=0;
            }else{
                src_index++;
            }
            count++;
        }else{
            sub_pointer->ch[sub_index]=src_pointer->ch[src_index];
            sub->len++;
            if(src_index==BLOCK_SIZE-1){//src中Block是否后移
                src_pointer=src_pointer->next;
                src_index=0;
            }else{
                src_index++;
            }
            if(sub_index==BLOCK_SIZE-1){//sub中Block是否分配并后移
                sub_pointer->next=(Block*)malloc(sizeof(Block));
                sub_pointer=sub_pointer->next;
                sub_pointer->next=NULL;
                sub_index=0;
            }else{
                sub_index++;
            }
        }
    }
//尾部操作
    if(sub_index!=0){//若最后Block非空,未填充部分用BLS_BLANK填充
        while(sub_index<=BLOCK_SIZE-1){
            sub_pointer->ch[sub_index]=BLS_BLANK;
            sub->tail=sub_pointer;
            sub_index++;
        }
    }else{//若最后Block为空,则删去并释放
        sub->tail=sub->head;
        while(sub->tail->next!=sub_pointer){
            sub->tail=sub->tail->next;
        }
        sub->tail->next=NULL;
        free(sub_pointer);
    }
    return true;
}